#include <GameEngine/UnitTest/unit_test.h>

#include <GameEngine/Geometry/CoordinateSystems/transformer3d_orientation.h>


#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif


//! Launch the unit tests on Transformer3dOrientation objects
/*!
 @return True if all unit tests on Transformer3dOrientation objects were
         succesful, false otherwise
 */
template <class T>
bool UnitTest::test_geometry_transformer3d_orientation_functions() {
	bool res = true;

	// Get number of bytes
	MemoryManager::BytesCount bytes = MemoryManager::instance()->bytes();

	// Create transformer
	GameEngine::Vector3d<T> from1 = GameEngine::Vector3d<T>(0,1,0);
	GameEngine::Vector3d<T> from2 = GameEngine::Vector3d<T>(1,0,0);
	GameEngine::Vector3d<T> from3 = GameEngine::Vector3d<T>(0,0,1);
	GameEngine::Vector3d<T> to1 = GameEngine::Vector3d<T>(1,0,1);
	GameEngine::Vector3d<T> to2 = GameEngine::Vector3d<T>(1,1,0);
	GameEngine::Vector3d<T> to3 = GameEngine::Vector3d<T>(0,1,1);
	GameEngine::Transformer3dOrientation<T> transformer(from1, from2, from3, to1, to2, to3);

	// Test orientation transform
	T tolerance = (T)0.00001;
	{{
		GameEngine::Vector3d<T> pt = transformer.transform(from1);
		res &= UNIT_TEST_ERROR( "[Transformer3dOrientation] Test transform()", ( pt.get_square_distance(to1) < tolerance ) );
		pt = transformer.transform(from2);
		res &= UNIT_TEST_ERROR( "[Transformer3dOrientation] Test transform()", ( pt.get_square_distance(to2) < tolerance ) );
		pt = transformer.transform(from3);
		res &= UNIT_TEST_ERROR( "[Transformer3dOrientation] Test transform()", ( pt.get_square_distance(to3) < tolerance ) );
	}}

	// Test inverse transform
	{{
		bool ok = false;
		GameEngine::Transformer3dOrientation<T> itransformer = transformer.inverse(&ok);
		res &= UNIT_TEST_ERROR( "[Transformer3dOrientation] Test inverse transform()", ok );
		GameEngine::Vector3d<T> pt = itransformer.transform(to1);
		res &= UNIT_TEST_ERROR( "[Transformer3dOrientation] Test inverse transform()", ( pt.get_square_distance(from1) < tolerance ) );
		pt = itransformer.transform(to2);
		res &= UNIT_TEST_ERROR( "[Transformer3dOrientation] Test inverse transform()", ( pt.get_square_distance(from2) < tolerance ) );
		pt = itransformer.transform(to3);
		res &= UNIT_TEST_ERROR( "[Transformer3dOrientation] Test inverse transform()", ( pt.get_square_distance(from3) < tolerance ) );
	}}

	// Get number of bytes
	res &= UNIT_TEST_ERROR( "[Transformer3dOrientation] Test memory leak", ( bytes == MemoryManager::instance()->bytes() ));

	// Return result
	return res;
}


#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif
